import gobject
import Sysaccess
import Exceptions

class Locations(gobject.GObject):
    '''this class is the container for location objects'''
    
    __gsignals__ = {
        # set signal is emit when a location is set 
        # callback has to look like : def callback(locations, location)
        'set' : (gobject.SIGNAL_RUN_LAST,gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
        # add signal is emit when a location is add
        # callback has to look like : def callback(locations, location)
        'add' : (gobject.SIGNAL_RUN_LAST ,gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
        # remove signal is emit when a location is remove
        # callback has to look like : def callback(locations, location_id) <-- id because this location does not exist anymore
        'remove' : (gobject.SIGNAL_RUN_LAST ,gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
    }
    
    def __init__(self,controller):
        '''constructor'''
        
        gobject.GObject.__init__(self)
        self.controller = controller        # a reference to the main controller
        self.id = None                      # unique identifier for location objects
        self.store = None                   # real container for location objects
        self.connect('set',self.save)       #\   
        self.connect('add',self.save)       #-auto save
        self.connect('remove',self.save)    #/
        self.attrib_to_load = ['name','automount','public_addr','local_addr','dns']
    
    def load(self):
        '''initialize the store and id with the saved pickle or default'''
        
        load = Sysaccess.load(self.controller.config.path['LOCATION PICKLE'])
        if load:
            self.id = load[0]
            self.store = {}
            for location_id,location in load[1].iteritems():
                new_location = Location(location_id)
                for attrib in self.attrib_to_load:
                    new_location.__dict__[attrib] = location.__dict__[attrib]
                self.store[location_id] = new_location
                
        else:
            raise Exceptions.PickleLoadException(self.controller.config.path['LOCATION PICKLE'])
            
    def load_defaults(self):
        self.id = 0
        everywhere = Location(0)
        everywhere.name = "Everywhere"
        self.store = {0 : everywhere}
        self.save()
        
    def save(self,*args):
        '''save store and id'''
        Sysaccess.save((self.id,self.store),self.controller.config.path['LOCATION PICKLE'])
    
    def get_id(self):
        '''generate an unique id to pass to Location constructor'''
        
        self.id += 1
        return self.id
    
    def __getitem__(self,item_id):
        '''getter'''
        
        return self.store[item_id]
    
    def __setitem__(self,item_id,location):
        '''setter witch emit add/set signal'''
        
        if item_id in self.store:
            self.store[item_id] = location
            self.emit('set',self.store[item_id])
        else :
            self.store[item_id] = location
            self.emit('add',self.store[item_id])
            
    def __delitem__(self,item_id):
        '''try to remove a location'''
        
        if item_id != 0 : # can't delete everywhere location
            del self.store[item_id]
            self.emit('remove',item_id)
        else :
            raise Exceptions.DelEverywhereLocation()
    
    def __iter__(self):
        '''iterator shortcut'''
        
        return self.store.iteritems()
    
    def __repr__(self):
        '''repr override'''
        
        return self.store.__repr__()
          
class Location():
    '''represent a location with it's network parameters'''
    
    def __init__(self,id):
        '''constructor'''
        
        self.id = id
        self.name = ""
        self.automount = False
        self.public_addr = []   # public ip address
        self.local_addr = []    # local ip address
        self.dns = []           # public domain name
    
    def add_param(self,type,value):
        '''add the give param in the right container only if it doesn't already exist'''
       
        ### param name --> config
        if type == 'public':
            if not value in self.public_addr:
                self.public_addr.append(value)
        elif type == 'local':
            if not value in self.local_addr:
                self.local_addr.append(value)
        elif type == 'dns':
            if not value in self.dns:
                self.dns.append(value)
                
    def clear_params(self):
        '''clear params store'''
        
        self.public_addr = []
        self.local_addr = []
        self.dns = []
        
    def __repr__(self):
        '''repr override'''
        return "%s (%s)" % (self.name,self.id)